package com.androidified.personalshopper.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ActionBar;
import android.app.ActionBar.OnNavigationListener;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import com.androidified.personalshopper.BuildConfig;
import com.androidified.personalshopper.BusProvider;
import com.androidified.personalshopper.CommerceProvider;
import com.androidified.personalshopper.Constants;
import com.androidified.personalshopper.R;
import com.androidified.personalshopper.bean.Commerce;
import com.androidified.personalshopper.bean.Promotion;
import com.androidified.personalshopper.model.CommerceModel;
import com.androidified.personalshopper.model.LocationInfoModel;
import com.androidified.personalshopper.ui.adapter.PromotionAdapter;
import com.littlefluffytoys.littlefluffylocationlibrary.LocationInfo;
import com.littlefluffytoys.littlefluffylocationlibrary.LocationLibrary;
import com.squareup.otto.Subscribe;

public class MainActivity extends Activity implements OnItemClickListener, OnClickListener {
	
	private LocationInfo lastEvent;
	
	private PromotionAdapter adapter;
	
	private ListView listView;
	private View see_map;
	private View loading;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		BusProvider.get().register(this);
		
		setContentView(R.layout.main_activity);
		findViews();
		setListeners();
		setupInitialData();
		
		loadFromCache();
	}
	
	private void findViews() {
		listView = (ListView) findViewById(R.id.listView);
		see_map = findViewById(R.id.see_map);
		loading = findViewById(R.id.loading);
	}

	private void setListeners() {
		listView.setOnItemClickListener(this);
		see_map.setOnClickListener(this);
	}

	private void setupInitialData() {
		listView.addHeaderView(getLayoutInflater().inflate(R.layout.search_header, null), null, false);
		
		adapter = new PromotionAdapter(this);
		listView.setAdapter(adapter);
		listView.setChoiceMode(ListView.CHOICE_MODE_NONE);
		
		getActionBar().setDisplayShowHomeEnabled(false);
		getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
		getActionBar().setTitle("");
		
		final List<Map<String, String>> data = new ArrayList<Map<String, String>>();
		
		Map<String, String> map = new HashMap<String, String>();
		map.put("id", "0");
		map.put("title", "Right now");
		data.add(map);

		map = new HashMap<String, String>();
		map.put("id", "1");
		map.put("title", getString(R.string.favorites));
		data.add(map);

		map = new HashMap<String, String>();
		map.put("id", "2");
		map.put("title", getString(R.string.featured));
		data.add(map);

		map = new HashMap<String, String>();
		map.put("id", "3");
		map.put("title", getString(R.string.your_friends));
		data.add(map);
		
		SimpleAdapter adapter = new SimpleAdapter(this, data, android.R.layout.simple_spinner_dropdown_item,
		    new String[] { "title" }, new int[] { android.R.id.text1});
		getActionBar().setListNavigationCallbacks(adapter, new OnNavigationListener() {
	        @Override
	        public boolean onNavigationItemSelected(int itemPosition, long itemId) {
	        	MainActivity.this.adapter.clear();
	        	loading.setVisibility(View.VISIBLE);
	        	new AsyncTask<Void, Void, Void>() {
	        		@Override
	        		protected Void doInBackground(Void... params) {
	        			Collections.shuffle(CommerceProvider.get());
	        			SystemClock.sleep((long) (Math.random() * 1000));
	        			return null;
	        		}
	        		protected void onPostExecute(Void result) {
	        			super.onPostExecute(result);
	        			showPromotions(CommerceProvider.get());
	        			loading.setVisibility(View.GONE);
	        		};
	        	}.execute();
	        	return true;
	        }
	    });
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main_activity_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.profile) {
			Intent intent = new Intent(this, ProfileActivity.class);
			startActivity(intent);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Subscribe public void onLocationUpdateEvent(LocationInfo event) {
		if (BuildConfig.DEBUG) Log.d(Constants.LOG_TAG, getClass().getSimpleName() +  ": onLocationUpdateEvent");
		
		/* The shouldUpdate check should be deleted in a future.
		 * We do this now because it takes about a minute to load
		 * all the necessary info from the Internet.
		 */
		if (lastEvent == null || CommerceModel.shouldUpdate(lastEvent, event)) {
			loading.setVisibility(View.VISIBLE);
			new AsyncTask<LocationInfo, Void, List<Commerce>>() {
				@Override
				protected List<Commerce> doInBackground(LocationInfo... info) {
					List<Commerce> commerces = CommerceModel.getNearRest(info[0].lastLat, info[0].lastLong, 1);
					if (BuildConfig.DEBUG) Log.d(Constants.LOG_TAG, getClass().getSimpleName() +  " - newLocationUpdate: ");
					CommerceModel.storeCache(MainActivity.this, commerces);
					LocationInfoModel.storeCache(MainActivity.this, info[0]);
					return commerces;
				}
				@Override
				protected void onPostExecute(List<Commerce> result) {
					super.onPostExecute(result);
					if (result != null) {
						CommerceProvider.set(result);
						showPromotions(result);
						loading.setVisibility(View.GONE);
					}
				};
			}.execute(event);
		}
		lastEvent = event;
	}
	
	private void loadFromCache() {
		loading.setVisibility(View.VISIBLE);
		new AsyncTask<Void, Void, List<Commerce>>() {
			@Override
			protected List<Commerce> doInBackground(Void... info) {
				List<Commerce> commerces = CommerceModel.getCache(MainActivity.this);
				lastEvent = LocationInfoModel.getCache(MainActivity.this);
				return commerces;
			}
			@Override
			protected void onPostExecute(List<Commerce> result) {
				super.onPostExecute(result);
				if (result == null) {
					LocationLibrary.forceLocationUpdate(getBaseContext());
				} else {
					CommerceProvider.set(result);
					showPromotions(result);
				}
			}
			
		}.execute();
	}
	
	private void showPromotions(List<Commerce> result) {
		ArrayList<Promotion> promotions = new ArrayList<Promotion>();
		for (Commerce commerce : result) {
			promotions.addAll(commerce.getPromotions());
		}
		adapter.addAll(promotions);
		loading.setVisibility(View.GONE);
		BusProvider.get().post(result);
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
		position -= listView.getHeaderViewsCount();
		if (position < 0) {
			return;
		}
		
		Intent intent = new Intent(this, DetailActivity.class);
    	intent.putExtra(DetailActivity.EXTRA_PROMO_ID, adapter.getItem(position).getId());
    	intent.putExtra(DetailActivity.EXTRA_COMMERCE_ID, adapter.getItem(position).getCommerce());
    	startActivity(intent);
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == see_map.getId()) {
			Intent intent = new Intent(this, MapActivity.class);
			startActivity(intent);
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		BusProvider.get().unregister(this);
	}
	
}
